package me.zhengjie.rest;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import me.zhengjie.annotation.rest.AnonymousPostMapping;
import me.zhengjie.domain.FormData;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;


import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;



@RestController
@RequestMapping("/maicailogin")
@RequiredArgsConstructor
@Api(tags = "")
public class AuthController {
    String windowsPath = "C:" + File.separator + "eladmin" + File.separator + "file";
    String linuxPath = "/tmp/file";

    @ApiOperation("接收文件")
    //@AnonymousAccess
    @AnonymousPostMapping(value = "/download")
    @ResponseBody
    public Map<String ,Object> download(@ModelAttribute FormData formData)throws Exception
    {
        Map<String,Object> map = new HashMap<>();
        File toFile = null;
        MultipartFile file = formData.getFile();
        if (file.getSize() <= 0) {//file.equals("") || file.getSize() <= 0
            map.put("msg", "空");
            return map;
        } else {
            String path = windowsPath;
            if(System.getProperty("os.name").toLowerCase().contains("linux"))
            {
                path = linuxPath;
            }


            /*获取文件原名称*/
            String originalFilename = file.getOriginalFilename();
            String name = originalFilename.substring(0, originalFilename.lastIndexOf("."));
            /*获取文件格式*/
            String fileFormat = originalFilename.substring(originalFilename.lastIndexOf("."));
            String date = formData.getDate();
            if(!(fileFormat.contains(".jpg") || fileFormat.contains(".mp4") || fileFormat.contains(".part")))
            {
                map.put("msg","格式错误");
                return map;
            }
            if(originalFilename.contains(".jpg"))
            {
                toFile = new File(path + File.separator+ "images" +File.separator
                        + date
                        + File.separator + name + fileFormat);
            }
            if(originalFilename.contains(".mp4"))
            {
                toFile = new File(path + File.separator+ "videos" +File.separator
                        + date
                        + File.separator + name + fileFormat);
            }
            if(originalFilename.contains("part"))
            {
                String absolutePath = null;
                try {
                    absolutePath = toFile.getCanonicalPath();
                    /*判断路径中的文件夹是否存在，如果不存在，先创建文件夹*/
                    String dirPath = absolutePath.substring(0, absolutePath.lastIndexOf(File.separator));
                    File dir = new File(dirPath);
                    if (!dir.exists()) {
                        dir.mkdirs();
                    }
                    InputStream ins = file.getInputStream();
                    inputStreamToFile(ins, toFile);
                    //String part = fileFormat.substring(fileFormat.lastIndexOf("t")+1);
                    //name.mp4size123.part1
                    String size = originalFilename.substring(originalFilename.lastIndexOf("size")+4,originalFilename.lastIndexOf("."));
                    File files = new File(dirPath);
                    File[] filesList = files.listFiles();
                    List<File> allFiles = new ArrayList<>();
                    for(File singleFile : filesList)
                    {
                        if(singleFile.getName().contains("part")&&singleFile.getName().contains(name))
                        {
                            allFiles.add(singleFile);
                        }
                    }
                    if(allFiles.size() == Integer.parseInt(size))
                    {
                        map = mergeFiles(name,dirPath,Integer.parseInt(size));
                        ins.close();
                        return map;
                    }
                    ins.close();
                    map.put("msg", "成功");
                    return map;

                } catch (IOException e) {
                    e.printStackTrace();
                    map.put("msg", "失败");
                    return map;
                }
            }
            String absolutePath = null;
            try {
                absolutePath = toFile.getCanonicalPath();

                /*判断路径中的文件夹是否存在，如果不存在，先创建文件夹*/
                String dirPath = absolutePath.substring(0, absolutePath.lastIndexOf(File.separator));
                File dir = new File(dirPath);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                InputStream ins = file.getInputStream();
                inputStreamToFile(ins, toFile);
                ins.close();

            } catch (IOException e) {
                e.printStackTrace();
                map.put("msg", "失败");
                return map;
            }
            map.put("msg","成功");
            return map;
        }
    }

    public Map<String , Object> mergeFiles(String fileName, String dirPath, int size)throws Exception
    {
        Map<String,Object> map = new HashMap<>();
        String targetFileName = fileName.substring(0,fileName.lastIndexOf("size"));
        BufferedOutputStream  bw = new BufferedOutputStream (Files.newOutputStream(Paths.get(dirPath + File.separator + targetFileName)));
        //List<File> files = new ArrayList<>();
        for (int i = 1; i <= size; i++) {
            String FileName= dirPath + File.separator + fileName + ".part" + i;
            File partFile = new File(FileName);
            BufferedInputStream bis = null;
            if(partFile.exists()) {
                try
                {
                    bis = new BufferedInputStream(Files.newInputStream(partFile.toPath()));
                    int length = -1;
                    byte[] bytes = new byte[1024*1024];
                    while((length = bis.read(bytes))!=-1){
                        bw.write(bytes,0,length);
                    }
                }
                catch (Exception e)
                {
                    bis.close();
                    bw.close();
                    map.put("msg","合并失败");
                    return map;
                }
            }
        }
        File files = new File(dirPath);

        File[] files1 = files.listFiles();
        for (File value : files1) {
            if (value.getName().contains("part") && value.getName().contains(fileName)) {
                value.delete();
            }
        }
        bw.close();

        map.put("msg","合并成功");
        return map;
    }

    //获取流文件
    private static void inputStreamToFile(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
